package cn.cloudreal.cbms.material.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.apache.commons.io.FileUtils;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.struts2.ServletActionContext;

import cn.cloudreal.cbms.common.util.Constants;
import cn.cloudreal.cbms.common.util.DatadicContext;
import cn.cloudreal.cbms.common.util.StringUtils;
import cn.cloudreal.cbms.material.service.MaterialService;
import cn.cloudreal.cbms.system.service.OrganizaService;
import cn.cloudreal.cbms.vo.Dictionary;
import cn.cloudreal.cbms.vo.Material;
import cn.cloudreal.cbms.vo.Organiza;
import cn.cloudreal.cbms.vo.UserInfo;

import com.opensymphony.xwork2.ActionSupport;

/**
 * <p>
 * Title: CBM
 * </p>
 * <p>
 * Description:物料批量导入
 * </p>
 * <p>
 * Copyright: Copyright (c) 2012
 * </p>
 * <p>
 * Company:云恒瑞通
 * </p>
 * 
 * @author liupanpan
 * @date 2012-08-14
 */
public class UploadMaterialAction extends ActionSupport {

	private MaterialService materialService = null;// 物料service
	private OrganizaService organizaService = null;
	private String noError = "";
	private String uploadErrorMessage = "";// 错误信息
	private File uploadFile = null;// 物料文件
	private String uploadFileFileName;
	private String uploadFileContentType;
	private List<Dictionary> dataListWLLX = null;// 物料类型
	private List<Dictionary> dataListWLYWLX = null;// 业务类型
	private List<Dictionary> dataListCITY = null;// 所属城市
	private List<Organiza> organizaLists = null;// 部门科室
	private List<Dictionary> dataListWLJB = null;// 物料级别

	public String doUploadMaterial() {
		String fliePath = "";// 上传文件路径
		String realpath = ServletActionContext.getServletContext().getRealPath(
				"/upload"); // 获得web应用的真实路径
		String fileName = "wuLiao_" + StringUtils.getMathAndTime() + ".xlsx";
		File savefile = new File(realpath, fileName); // 参数1：保存路径，参数2：文件名
		try {
			FileUtils.copyFile(uploadFile, savefile);
		} catch (IOException e) {
			e.printStackTrace();
			return ERROR;
		}
		fliePath = realpath + "/" + fileName;

		// 解析excel
		Workbook workbook = null;
		try {
			workbook = this.create(new FileInputStream(fliePath));
		} catch (Exception e) {
			e.printStackTrace();
			this.deleteFile(fliePath);
			return ERROR;
		}
		try {
			UserInfo userInfo = (UserInfo) ServletActionContext.getRequest()
					.getSession().getAttribute(Constants.SESSIONPRKEY);
			String cityKey = userInfo.getUsercity();
			dataListWLLX = DatadicContext.getInstance().getDicDataListByCode(
					"WLLX");// 物料类型
			dataListWLYWLX = DatadicContext.getInstance().getDicDataListByCode(
					"WLYWLX");// 业务类型
			// dataListCITY =
			// DatadicContext.getInstance().getSubDatadicByCode("-1", "CITY");//
			// 归属地市
			dataListWLJB = DatadicContext.getInstance().getDicDataListByCode(
					"WLJB");// 物料级别
			for (int k = 0; k < workbook.getNumberOfSheets(); k++) {
				Sheet sheet = workbook.getSheetAt(k);
				String sheetName = sheet.getSheetName(); // sheet名字
				int rows = sheet.getPhysicalNumberOfRows();
				for (int r = 1; r < rows; r++) {
					Row row = (Row) sheet.getRow(r);
					if (row == null) {
						break;
					}
					if (row != null) {
						boolean bool = true;// 提示
						Material material = new Material();
						material.setMaterialName(this.getValue(row.getCell(0))
								.trim());
						if (!"".equals(material.getMaterialName())
								&& StringUtils.getStringLength(material
										.getMaterialName()) > 60) {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，物料名称不能为空或长度不能大于30汉字(60字符)！<br/>";
							bool = false;
							continue;
						}

						if (!"".equals(material.getMaterialName())
								&& StringUtils.StringFilter_Bool(material
										.getMaterialName())) {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，物料名称里有特殊字符！<br/>";
							bool = false;
							continue;
						}

						String materialType = "";// 物料类型
						if (dataListWLLX != null && dataListWLLX.size() != 0) {
							for (int i = 0; i < dataListWLLX.size(); i++) {
								if (this.getValue(row.getCell(1)).trim()
										.equals(
												dataListWLLX.get(i)
														.getDatavalue())) {
									materialType = dataListWLLX.get(i).getId()
											+ "";
									break;
								}
							}
						}
						if (!"".equals(materialType) && materialType != null) {
							material.setMaterialType(materialType);// 物料类型
						} else {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，物料类型不能为空或格式错误！<br/>";
							bool = false;
							continue;
						}

						String materailLevel = "";// 物料级别
						if (dataListWLJB != null && dataListWLJB.size() != 0) {
							for (int i = 0; i < dataListWLJB.size(); i++) {
								if (this.getValue(row.getCell(2)).trim()
										.equals(
												dataListWLJB.get(i)
														.getDatavalue())) {
									materailLevel = dataListWLJB.get(i).getId()
											+ "";
									break;
								}

							}
						}
						if (!"".equals(materailLevel) && materailLevel != null) {
							material.setMaterialLevel(materailLevel);// 物料级别
						} else {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，物料级别不能为空或格式错误！<br/>";
							bool = false;
							continue;
						}

						String serviceType = "";// 业务类型
						if (dataListWLYWLX != null
								&& dataListWLYWLX.size() != 0) {
							for (int i = 0; i < dataListWLYWLX.size(); i++) {
								if (this.getValue(row.getCell(3)).trim()
										.equals(
												dataListWLYWLX.get(i)
														.getDatavalue())) {
									serviceType = dataListWLYWLX.get(i).getId()
											+ "";
									break;
								}
							}
						}
						if (!"".equals(serviceType) && serviceType != null) {
							material.setServiceType(serviceType);// 业务类型
						} else {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，业务类型不能为空或格式错误！<br/>";
							bool = false;
							continue;
						}

						material.setOwnCity(cityKey);// 归属地市

						organizaLists = organizaService
								.getOrganizaByCity(cityKey);// 部门科室list
						String ownDepartmentValue = this.getValue(
								row.getCell(4)).trim();// 部门科室
						if (StringUtils.StringFilter_Bool(ownDepartmentValue)) {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，部门科室不能包含特殊字符！<br/>";
							bool = false;
							continue;
						}

						String ownDepartment = "";
						if (ownDepartmentValue != null
								&& !"".equals(ownDepartmentValue)) {
							if (organizaLists != null
									&& organizaLists.size() != 0) {
								for (int i = 0; i < organizaLists.size(); i++) {
									if (ownDepartmentValue.equals(organizaLists
											.get(i).getOrgName().trim())) {
										ownDepartment = organizaLists.get(i)
												.getOrgCode();
										break;
									}
								}
							}
							if (!"".equals(ownDepartment)
									&& ownDepartment != null) {
								material.setOwnDepartment(ownDepartment);// 部门科室
							} else {
								uploadErrorMessage += sheetName + ",第"
										+ (r + 1) + "行，部门科室不存在！<br/>";
								bool = false;
							}
						}

						if (isValidDate(getValue(row.getCell(5)).trim())
								&& !"".equals(getValue(row.getCell(5)).trim())) {
							material.setFirstUpTime(getValue(row.getCell(5))
									.trim());// 开始时间
						} else {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，最初上线时间不能为空或者格式不正确！<br/>";
							bool = false;
							continue;
						}

						material.setAccessory(this.getValue(row.getCell(6))
								.trim());// 物料描述
						System.out.println(StringUtils.getStringLength(material
								.getAccessory()));
						if (StringUtils
								.getStringLength(material.getAccessory()) > 160) {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，物料描述长度不能大于80汉字(160字符)！<br/>";
							bool = false;
						}

						String orderCol = this.getValue(row.getCell(7)).trim();// 排序字段
						if (!"".equals(orderCol) && isFloathString(orderCol)) {
							material.setOrderCol(Integer.parseInt(orderCol));
						} else {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，物料排序不能为空或不是整数！<br/>";
							bool = false;
							continue;
						}

						if (StringUtils.StringFilter_Bool(orderCol)) {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，物料排序含有特殊字符！<br/>";
							bool = false;
							continue;
						}

						if (Float.parseFloat(orderCol) - 99 > 0
								|| Float.parseFloat(orderCol) < 0.0) {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，物料排序应0-99的整数！<br/>";
							bool = false;
							continue;
						}

						String materialID = this.getTheMaterialId(material);// 物料编号
						material.setMaterialID(materialID);

						if (!materialService.isTheUniqueId(materialID)) {
							uploadErrorMessage += sheetName + ",第" + (r + 1)
									+ "行，该物料信息已存在！<br/>";
							bool = false;
							continue;
						}
						if (bool) {
							materialService.addMaterial(material);// 添加物料
							this.deleteFile(fliePath);// 删除物料文件
						}
					}
				}
			}
			System.out.println(uploadErrorMessage);
			if ("".equals(uploadErrorMessage)) {
				noError = "noError";
			}
		} catch (Exception e) {
			e.printStackTrace();
			this.deleteFile(fliePath);// 删除物料文件
			return ERROR;
		}
		return SUCCESS;
	}

	/**
	 * 判断是否整数
	 * 
	 * @param testString
	 * @return
	 */
	private boolean isNumberString(String testString) {
		String numAllString = "0123456789";
		if (testString.length() <= 0)
			return false;
		for (int i = 0; i < testString.length(); i++) {
			String charInString = testString.substring(i, i + 1);
			if (!numAllString.contains(charInString))
				return false;
		}
		return true;
	}

	/**
	 * 判断是否Float
	 * 
	 * @param testString
	 * @return
	 */
	public boolean isFloathString(String testString) {
		if (!testString.contains(".")) {
			return isNumberString(testString);
		} else {
			String[] floatStringPartArray = testString.split("\\.");
			if (floatStringPartArray.length == 2) {
				if (isNumberString(floatStringPartArray[0]) == true
						&& isNumberString(floatStringPartArray[1]) == true)
					return true;
				else
					return false;
			} else
				return false;

		}
	}

	/**
	 * 判断是否日期
	 * 
	 * @param s
	 * @return
	 */
	private boolean isValidDate(String s) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		dateFormat.setLenient(false);
		try {
			dateFormat.parse(s);
			return true;
		} catch (Exception e) {
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			return false;
		}
	}

	/**
	 * 得到Excel表中的值
	 * 
	 * @param hssfCell
	 *            Excel中的每一个格子
	 * @return Excel中每一个格子中的值
	 */
	public String getValue(Cell hssfCell) {
		if (hssfCell == null) {
			return "";
		}
		if (hssfCell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN) {
			// 返回布尔类型的值
			return String.valueOf(hssfCell.getBooleanCellValue()).trim();
		}
		if (hssfCell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
			if (HSSFDateUtil.isCellDateFormatted(hssfCell)) {
				SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
				Date dt = HSSFDateUtil.getJavaDate(hssfCell
						.getNumericCellValue());
				return dateformat.format(dt).trim();
			} else {
				// 返回数值类型的值
				String str = String.valueOf(hssfCell.getNumericCellValue())
						.trim();
				if (isFloathString(str)) {
					double num = Double.parseDouble("0"
							+ str.substring(str.indexOf(".")));
					if (num == 0.0) {
						int num2 = Integer.parseInt(str.substring(0, str
								.indexOf(".")));
						return String.valueOf(num2);
					} else {
						return str;
					}
				}
			}
		}
		// 返回字符串类型的值
		return String.valueOf(hssfCell.getStringCellValue()).trim();
	}

	/**
	 * 删除单个文件
	 * 
	 * @param sPath
	 *            被删除文件的文件名
	 * @return 单个文件删除成功返回true，否则返回false
	 */
	public boolean deleteFile(String sPath) {
		boolean flag = false;
		File file = new File(sPath);
		// 路径为文件且不为空则进行删除
		if (file.isFile() && file.exists()) {
			file.delete();
			flag = true;
		}
		return flag;
	}

	private Workbook create(InputStream inp) throws IOException,
			InvalidFormatException {
		if (!inp.markSupported()) {
			inp = new PushbackInputStream(inp, 8);
		}
		if (POIFSFileSystem.hasPOIFSHeader(inp)) {
			return new HSSFWorkbook(inp);
		}
		if (POIXMLDocument.hasOOXMLHeader(inp)) {
			return new XSSFWorkbook(OPCPackage.open(inp));
		}
		throw new IllegalArgumentException("你的excel版本目前poi解析不了");
	}

	/**
	 * 获取物料编号
	 */
	private String getTheMaterialId(Material mat) {
		String name = mat.getMaterialName();// 物料名称
		String city = mat.getOwnCity();// 归属地
		String service = mat.getServiceType();// 业务类型
		String type = mat.getMaterialType();// 物料类型
		int order = mat.getOrderCol();// 物料排序
		String firstTime = mat.getFirstUpTime();// 最初上线时间
		String sub1 = firstTime.substring(2, 4);
		String sub2 = firstTime.substring(5, 7);
		String sub = sub1 + sub2;
		String orderOfSring = String.valueOf(order);
		if (orderOfSring.length() < 2) {
			orderOfSring = "0" + orderOfSring;
		}
		String materialID = city + "-" + service + "-" + type + "-" + sub + "-"
				+ orderOfSring + "-" + name;
		// System.out.println(materialID);
		return materialID;

	}

	public String getNoError() {
		return noError;
	}

	public void setNoError(String noError) {
		this.noError = noError;
	}

	public String getUploadErrorMessage() {
		return uploadErrorMessage;
	}

	public void setUploadErrorMessage(String uploadErrorMessage) {
		this.uploadErrorMessage = uploadErrorMessage;
	}

	public void setMaterialService(MaterialService materialService) {
		this.materialService = materialService;
	}

	public File getUploadFile() {
		return uploadFile;
	}

	public void setUploadFile(File uploadFile) {
		this.uploadFile = uploadFile;
	}

	public String getUploadFileFileName() {
		return uploadFileFileName;
	}

	public void setUploadFileFileName(String uploadFileFileName) {
		this.uploadFileFileName = uploadFileFileName;
	}

	public String getUploadFileContentType() {
		return uploadFileContentType;
	}

	public void setUploadFileContentType(String uploadFileContentType) {
		this.uploadFileContentType = uploadFileContentType;
	}

	public void setOrganizaService(OrganizaService organizaService) {
		this.organizaService = organizaService;
	}

	public static void main(String[] args) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		dateFormat.setLenient(false);
		try {
			dateFormat.parse("20122-05-01");
			System.out.println(true);
		} catch (Exception e) {
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			System.out.println(false);
		}
	}
}
